package com.jml.proxy;

import com.jml.annotation.JmlFeignClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class FeignClientProxy {

 
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private JmlInvocationHandler jmlInvocationHandler;

    public FeignClientProxy() {
    }

    private static final FeignClientProxy feignClientProxy = new FeignClientProxy();


    public static FeignClientProxy getFeignClientProxy() {
        return feignClientProxy;
    }


    public <T> T create(Class<T> tClass) {
        return (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class<?>[]{tClass}, jmlInvocationHandler);
    }


    public <T> T createTest(Class<T> tClass) {
        return (T) Proxy.newProxyInstance(tClass.getClassLoader(), new Class[]{tClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //1.使用java反射机制获取到接口上服务名称
                JmlFeignClient jmlFeignClient = tClass.getDeclaredAnnotation(JmlFeignClient.class);
                if (jmlFeignClient == null) {
                    throw new Exception(" not  is JmlFeignClient");
                }
                String serviceName = jmlFeignClient.value();
                if (StringUtils.isEmpty(serviceName)) {
                    throw new Exception(" serviceName  is null");
                }
                // 2.请求接口地址
                GetMapping declaredAnnotation = method.getAnnotation(GetMapping.class);
                if (declaredAnnotation == null) {
                    throw new Exception(" declaredAnnotation  is null");
                }
                String[] requestNames = declaredAnnotation.value();
                String requestName = requestNames[0];
                // 3.使用restTemplate发送Rest请求 支持本地负载均衡模式
                ResponseEntity<?> result = restTemplate.getForEntity("http://" + serviceName + requestName, method.getReturnType());
                return result.getBody();
            }
        });
    }
}
